package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.exception.BizException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.Consumer;
import com.mingqijia.gassafety.db.entity.RunningStrategy;
import com.mingqijia.gassafety.db.entity.ServicePkgRecord;
import com.mingqijia.gassafety.db.entity.WarnStrategy;
import com.mingqijia.gassafety.db.mapper.ServicePkgRecordMapper;
import com.mingqijia.gassafety.shared.constant.BusinessNoticeParam;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.ServicePkgEnum;
import com.mingqijia.gassafety.shared.dto.LogVO;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.webserver.request.FuncAreaIdRequest;
import com.mingqijia.gassafety.webserver.request.ServicePkgRecordListReq;
import com.mingqijia.gassafety.webserver.request.ServicePkgRecordReq;
import com.mingqijia.gassafety.webserver.response.ServicePkgRecordContentResp;
import com.mingqijia.gassafety.webserver.response.ServicePkgRecordListResp;
import com.mingqijia.gassafety.webserver.service.*;
import com.mingqijia.gassafety.webserver.utils.LogRecordAspect;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务套餐实现类
 */


@Service
@Slf4j
public class ServicePkgRecordServiceImpl extends ServiceImpl<ServicePkgRecordMapper, ServicePkgRecord> implements ServicePkgRecordService {

    @Autowired
    private ConfigureHolder holder;

    @Autowired
    private ConsumerService consumerService;

    @Autowired
    private WarnStrategyService warnStrategyService;

    @Autowired
    private RunningStrategyService runningStrategyService;

    @Autowired
    private ConsumerServiceInfoService consumerServiceInfoService;

    @Autowired
    private BusinessNoticeService businessNoticeService;

    @Override
    public PageUtil<ServicePkgRecordListResp> businessAreaList(ServicePkgRecordListReq req) {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<ServicePkgRecord> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ServicePkgRecord::getSpId, spId).like(!StringUtils.isEmpty(req.getPgkName()), ServicePkgRecord::getPgkName, req.getPgkName())
                .like(!StringUtils.isEmpty(req.getServiceContent()), ServicePkgRecord::getServiceContent, req.getServiceContent())
                .eq(req.getPgkCycle() != null && req.getPgkCycle() > 0, ServicePkgRecord::getPgkCycle, req.getPgkCycle())
                .eq(!StringUtils.isEmpty(req.getPgkCycleUnit()), ServicePkgRecord::getPgkCycleUnit, req.getPgkCycleUnit())
                .eq(ServicePkgRecord::getIsDeleted, Constants.IS_DELETED_FALSE);
        lqw.orderByDesc(ServicePkgRecord::getCreatedAt);
        Page<ServicePkgRecord> page = PageHelper.startPage(req.getPage(), req.getPageSize());
        List<ServicePkgRecord> list = this.list(lqw);
        List<Integer> idList = list.stream().map(ServicePkgRecord::getId).collect(Collectors.toList());
        Map<Integer, List<Consumer>> consumerMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(idList)) {
            LambdaQueryWrapper<Consumer> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Consumer::getPkgId, idList)
                    .eq(Consumer::getIsDeleted, 0);
            List<Consumer> consumerList = consumerService.list(queryWrapper);
            if (CollectionUtils.isNotEmpty(consumerList)) {
                consumerMap = consumerList.stream().collect(Collectors.groupingBy(Consumer::getPkgId));
            }
        }
        //List<DictionaryItemRespDTO> areaList = holder.getDictionaryByKey(Constants.DICTIONARY_SERVICE_PKG);
        Map<String, String> dictMap = ServicePkgEnum.getMap();
        Map<Integer, List<Consumer>> finalConsumerMap = consumerMap;
        List<ServicePkgRecordListResp> pkgRecordListResps = list.stream().map(item -> {
            ServicePkgRecordListResp response = new ServicePkgRecordListResp();
            BeanUtils.copyProperties(item, response);
            if (StringUtils.isNotEmpty(item.getServiceContent())) {
                String[] serviceContents = item.getServiceContent().split(",");
                StringBuilder sb = new StringBuilder();
                for (String serviceContent : serviceContents) {
                    sb.append(dictMap.get(serviceContent)).append("；");
                }
                response.setServiceContent(sb.toString().substring(0, sb.length() -1));
            }
            response.setDataSourceName("报警监控系统");
            if (finalConsumerMap.containsKey(response.getId())) {
                response.setConsumerSum(finalConsumerMap.get(response.getId()).size());
            } else {
                response.setConsumerSum(0);
            }
            return response;
        }).collect(Collectors.toList());
        PageUtil pageInfo = new PageUtil<>(req.getPage(), req.getPageSize(), page.getTotal(), pkgRecordListResps);
        return pageInfo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(ServicePkgRecordReq req) {
        String spId = ApplicationUtils.getWorkingSpId();
        //查询服务套餐名称师傅存在
        LambdaQueryWrapper<ServicePkgRecord> runningStrategyWrapper = new LambdaQueryWrapper<>();
        runningStrategyWrapper.eq(ServicePkgRecord::getPgkName, req.getPgkName())
                .eq(ServicePkgRecord::getIsDeleted, 0)
                .like(ServicePkgRecord::getSpId, spId);
        List<ServicePkgRecord> pkgRecords = this.list(runningStrategyWrapper);
        if (CollectionUtils.isNotEmpty(pkgRecords)) {
            throw new BizException("服务套餐名称已经存在");
        }
        if (StringUtils.isNotEmpty(req.getServiceContent())) {
            String[] split = req.getServiceContent().split(",");
            Arrays.sort(split);
            StringBuilder sb = new StringBuilder();
            for (String key : split) {
                sb.append(key).append(",");
            }
            req.setServiceContent(sb.toString().substring(0, sb.length() - 1));
        }
        ServicePkgRecord servicePkgRecord = new ServicePkgRecord();

        servicePkgRecord.setPgkName(req.getPgkName());
        servicePkgRecord.setServiceContent(req.getServiceContent());
        //servicePkgRecord.setTwoServiceContent(req.getTwoServiceContent());
        servicePkgRecord.setPgkCycle(req.getPgkCycle());
        servicePkgRecord.setPgkCycleUnit(req.getPgkCycleUnit());
        servicePkgRecord.setDataSource(1);
        servicePkgRecord.setIsDeleted(false);
        servicePkgRecord.setSpId(spId);
        servicePkgRecord.setCreatedAt(new DateTime());
        servicePkgRecord.setUpdatedAt(new DateTime());
        this.save(servicePkgRecord);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean edit(ServicePkgRecordReq req) {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<ServicePkgRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServicePkgRecord::getId, req.getId()).eq(ServicePkgRecord::getSpId, spId);
        ServicePkgRecord servicePkgRecord = this.getOne(queryWrapper);
        if (servicePkgRecord == null) {
            throw new BizException("该套餐id,对应套餐不存在!");
        }
        if (StringUtils.isNotEmpty(req.getServiceContent())) {
            String[] split = req.getServiceContent().split(",");
            Arrays.sort(split);
            StringBuilder sb = new StringBuilder();
            for (String key : split) {
                sb.append(key).append(",");
            }
            req.setServiceContent(sb.toString().substring(0, sb.length() - 1));
        }
        StringBuilder sb = new StringBuilder();
        sb.append("【").append(req.getPgkName()).append("】的服务内容");
        if (!StringUtils.equals(servicePkgRecord.getServiceContent(), req.getServiceContent())) {
            sb.append("\n 服务内容由【").append(servicePkgRecord.getServiceContent()).append("】变更为【").append(req.getServiceContent()).append("】");
        }
        servicePkgRecord.setServiceContent(req.getServiceContent());
        //servicePkgRecord.setTwoServiceContent(req.getTwoServiceContent());
        servicePkgRecord.setUpdatedAt(new DateTime());
        this.updateById(servicePkgRecord);
        //企业级操作日志
        LogVO vo = new LogVO();
        String commomInfo =  req.getPgkName() ;
        vo.setDetail(sb.toString());
        vo.setCommonInfo(commomInfo);
        vo.setStrategyType("编辑");
        LogRecordAspect.threadLocal.set(vo);
        return true;
    }

    @Override
    public ServicePkgRecordListResp detail(Integer id) {
        String spId = ApplicationUtils.getWorkingSpId();
        ServicePkgRecordListResp pkgRecordListResp = new ServicePkgRecordListResp();
        LambdaQueryWrapper<ServicePkgRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServicePkgRecord::getId, id).eq(ServicePkgRecord::getSpId, spId);
        ServicePkgRecord pkgRecord = this.getOne(queryWrapper);
        if (pkgRecord == null) {
            throw new BizException("该套餐id,对应套餐不存在!");
        }
        BeanUtils.copyProperties(pkgRecord, pkgRecordListResp);
        pkgRecordListResp.setDataSourceName("报警监控系统");
        return pkgRecordListResp;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean delete(FuncAreaIdRequest req) {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<ServicePkgRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ServicePkgRecord::getId, req.getId()).eq(ServicePkgRecord::getSpId, spId);
        ServicePkgRecord pkgRecord = this.getOne(queryWrapper);
        if (pkgRecord == null) {
            throw new BizException("该套餐id,对应套餐不存在!");
        }
        pkgRecord.setIsDeleted(true);
        this.updateById(pkgRecord);
        //删除客户绑定套餐
        LambdaUpdateWrapper<Consumer> consumerUpdateWrapper = new LambdaUpdateWrapper<>();
        consumerUpdateWrapper.set(Consumer::getPkgId, 0)
                .set(Consumer::getPkgName, "")
                .eq(Consumer::getPkgId, req.getId());
        consumerService.update(consumerUpdateWrapper);
        //删除报警策略绑定套餐
        LambdaQueryWrapper<WarnStrategy> warnStrategyWrapper = new LambdaQueryWrapper<>();
        warnStrategyWrapper.eq(WarnStrategy::getStrategyObj, 3)
                .like(WarnStrategy::getStrategyObjValues, req.getId());
        List<WarnStrategy> warnStrategyList = warnStrategyService.list(warnStrategyWrapper);
        if (CollectionUtils.isNotEmpty(warnStrategyList)) {
            for (WarnStrategy warnStrategy : warnStrategyList) {
                String[] strategyObjList = warnStrategy.getStrategyObjValues().split(WarnStrategyServiceImpl.split);
                StringBuilder sb = new StringBuilder();
                for (String strategyObj : strategyObjList) {
                    if (!req.getId().toString().equals(strategyObj)) {
                        sb.append(strategyObj).append(WarnStrategyServiceImpl.split);
                    }
                }
                if (sb.length() > 0) {
                    warnStrategy.setStrategyObjValues(sb.toString());
                } else {
                    warnStrategy.setStrategyObjValues("");
                }
            }
            warnStrategyService.updateBatchById(warnStrategyList);
        }
        //删除绑定设备情况策略套餐
        LambdaQueryWrapper<RunningStrategy> runningStrategyWrapper = new LambdaQueryWrapper<>();
        runningStrategyWrapper.eq(RunningStrategy::getStrategyObj, 3)
                .like(RunningStrategy::getStrategyObjValues, req.getId());
        List<RunningStrategy> runningStrategyList = runningStrategyService.list(runningStrategyWrapper);
        if (CollectionUtils.isNotEmpty(runningStrategyList)) {
            for (RunningStrategy runningStrategy : runningStrategyList) {
                String[] strategyObjList = runningStrategy.getStrategyObjValues().split(",");
                StringBuilder sb = new StringBuilder();
                for (String strategyObj : strategyObjList) {
                    if (!strategyObj.equals(req.getId().toString())) {
                        sb.append(strategyObj).append(",");
                    }
                }
                if (sb.length() > 0) {
                    runningStrategy.setStrategyObjValues(sb.toString().substring(0 ,sb.length() -1));
                } else {
                    runningStrategy.setStrategyObjValues("");
                }
            }
            runningStrategyService.updateBatchById(runningStrategyList);
        }
        //企业级操作日志
        LogVO vo = new LogVO();
        String detail = "删除【" + pkgRecord.getPgkName() + "】";
        String commomInfo =  pkgRecord.getPgkName() ;
        vo.setDetail(detail);
        vo.setCommonInfo(commomInfo);
        vo.setStrategyType("删除");
        LogRecordAspect.threadLocal.set(vo);
        return true;
    }

    @Override
    public List<ServicePkgRecordContentResp> serviceContent() {
        List<ServicePkgRecordContentResp> recordContentResps = new ArrayList<>();
        Map<String, String> areaList = ServicePkgEnum.getMap();
        for (String key : areaList.keySet()) {
            ServicePkgRecordContentResp resp = new ServicePkgRecordContentResp();
            resp.setCode(key);
            resp.setName(areaList.get(key));
            recordContentResps.add(resp);
        }
        Collections.sort(recordContentResps, Comparator.comparing(ServicePkgRecordContentResp::getCode));
        return recordContentResps;
    }

    @Override
    public List<String> servicePkgSendConfig(Consumer consumer, String imei, Boolean servicePkgModeSwitch) {
        List<String> selections = new ArrayList<>();
        if (!servicePkgModeSwitch){
            log.info("servicePkgSendConfig servicePkgModeSwitch未开启");
            return selections;
        }
        if (consumer == null || consumer.getId() == 0 || null == consumer.getPkgId() || consumer.getPkgId() == 0) {
            log.info("servicePkgSendConfig 客户未配置服务套餐 consumer:{}",JSONObject.toJSONString(consumer));
            return selections;
        }
        if (consumerServiceInfoService.checkConsumerImeiServiceDate(consumer.getSpId(), consumer.getId(), imei)) {
            ServicePkgRecord servicePkgRecord = this.getBaseMapper().selectById(consumer.getPkgId());
            String serviceContent = servicePkgRecord.getServiceContent();
            if (StringUtils.isNotEmpty(serviceContent)) {
                selections.addAll(Arrays.asList(serviceContent.split(",")));
            }
        }
        log.info("servicePkgSendConfig selections:{}", JSONObject.toJSONString(selections));
        return selections;
    }

    @Override
    public Boolean checkOwnerServiceContentCode(String spId, Integer consumerId, Integer pkgId, String imei, String serviceContentCode) {
        log.info("checkOwnerServiceContentCode==>>spId:{},consumerId:{},pkgId:{},imei:{},serviceContentCode:{}",
                spId,consumerId,pkgId,imei,serviceContentCode);
        Boolean servicePkgModeSwitch = businessNoticeService.switchValueByCode(
                BusinessNoticeParam.DIFFERENT_SERVICE_PACKAGE_MODE.getCode(),
                spId
        );
        if (!servicePkgModeSwitch){
            log.info("checkOwnerServiceContentCode==>>开关未开启");
            return true;
        }else if (-1 == pkgId && null != consumerId && consumerId > 0) {
            Consumer consumer = consumerService.getById(consumerId);
            pkgId = consumer.getPkgId();
            log.info("checkOwnerServiceContentCode==>>pkgId:{}",pkgId);
        }
        if (null == pkgId || pkgId == 0 || null == consumerId || consumerId == 0) {
            return false;
        }
        List<String> selections = new ArrayList<>();
        if (consumerServiceInfoService.checkConsumerImeiServiceDate(spId, consumerId, imei)) {
            ServicePkgRecord servicePkgRecord = this.getBaseMapper().selectById(pkgId);
            log.info("checkOwnerServiceContentCode==>>servicePkgRecord:{}", JSONObject.toJSONString(servicePkgRecord));
            if (null == servicePkgRecord) {
                return false;
            }
            String serviceContent = servicePkgRecord.getServiceContent();
            if (StringUtils.isNotEmpty(serviceContent)) {
                selections.addAll(Arrays.asList(serviceContent.split(",")));
            }
            log.info("checkOwnerServiceContentCode==>>selections:{}",JSONObject.toJSONString(selections));
        }
        return selections.contains(serviceContentCode);
    }

    @Override
    public Integer checkConsumer(Integer id) {
        LambdaQueryWrapper<Consumer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Consumer::getPkgId, id)
                .eq(Consumer::getIsDeleted, 0);
        int count = consumerService.count(queryWrapper);
        return count;
    }
}
